package controllers;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.NamespaceManager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import play.mvc.Http.StatusCode;
import play.mvc.Scope.Session;
import models.Residence;
import models.BaseModel;
import models.Subscriber;
import models.User;
import exceptions.ValidationException;
import play.Logger;
import play.i18n.Messages;
import play.mvc.Before;
import play.mvc.Catch;
import play.mvc.Controller;
import play.server.ServletWrapper;
import services.image.ImageSearchService;
import utils.constants.SessionConstants;

public class BaseController extends Controller {
	
	protected static final int LIMIT = 50;
	
	@Before
	static void addDefaults() {
		User user = Security.getCurrentUser(Session.current().get(SessionConstants.USER));
		if(user!=null) {
			String username = Session.current().get(SessionConstants.USER);
			if(username.contains("@")){
				NamespaceManager.set(username.substring(username.indexOf("@")+1));
			} else {
				NamespaceManager.set(null);
			}
		}
	    renderArgs.put("appTitle", Messages.get("app.title"));
	    renderArgs.put("user", user);
	}
	
	@Catch(ValidationException.class)
    public static void manageValidationException(Throwable throwable) {
		response.status = StatusCode.BAD_REQUEST;
		ValidationException validationException = (ValidationException) throwable;
		Map<String, String> errorsMap = new HashMap<String, String>();
		for(play.data.validation.Error error : validationException.getErrors()) {
			if(error.getKey().contains(".")) {
				errorsMap.put(error.getKey().substring(error.getKey().indexOf(".")+1), 
						error.message());
				
			}
		}
		renderJSON(errorsMap);
    }
	
	
	public static <T> void renderJSONList(Data<T> data) throws SecurityException, NoSuchFieldException {
		Field field = data.getClass().getDeclaredField("data");
		ParameterizedType fieldType = (ParameterizedType) field.getGenericType();
		Type dataType =  fieldType.getActualTypeArguments()[0];
		renderJSON(gson().toJson(data, dataType));
	}
	
	public static Gson gson() {	
		Gson gson = new GsonBuilder().registerTypeAdapter(java.util.Date.class, new	
				JsonDeserializer<java.util.Date>() {
				@Override
				public java.util.Date deserialize(com.google.gson.JsonElement p1,
						java.lang.reflect.Type p2,com.google.gson.JsonDeserializationContext p3) {
					return new java.util.Date(p1.getAsLong());
				}}).registerTypeAdapter(java.util.Date.class, new
				JsonSerializer<java.util.Date>() {
			@Override
			public JsonElement serialize(java.util.Date src, Type typeOfSrc,
					com.google.gson.JsonSerializationContext context) {
				return new JsonPrimitive(src.getTime());
			}
		}).create();
		return gson;
	}
	
	protected static HttpServletResponse getHttpServletResponse() { 
        return (HttpServletResponse) request.args.get(ServletWrapper.SERVLET_RES);
    }
	
}
